<template>
  <div class="min-h-screen bg-gray-50">
    <!-- 顶部导航栏 -->
    <div class="bg-white shadow-sm border-b fixed top-0 left-0 right-0 z-50">
      <div class="container mx-auto px-4 py-3">
        <div class="flex items-center justify-between">
          <div class="flex items-center space-x-4">
            <button
              @click="goBackToSelect"
              class="flex items-center px-3 py-2 text-gray-600 hover:text-gray-800 transition-colors"
            >
              <svg class="w-5 h-5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
              </svg>
              返回
            </button>
            <div class="border-l border-gray-300 pl-4">
              <h1 class="text-xl font-semibold text-gray-800">
                {{ currentExample?.title || currentAssignment?.title || '代码编辑器' }}
              </h1>
              <span
                v-if="currentAssignment"
                :class="getDifficultyClass(currentAssignment.difficulty)"
                class="inline-block px-2 py-1 rounded text-xs font-medium mt-1"
              >
                {{ getDifficultyText(currentAssignment.difficulty) }}
              </span>
              <!-- <span
                v-if="currentExample"
                class="inline-block px-2 py-1 rounded text-xs font-medium mt-1 bg-purple-100 text-purple-800"
              >
                示例代码
              </span> -->
            </div>
          </div>
          <div class="flex items-center space-x-2">
            <!-- <button
              @click="toggleScoreStandard"
              class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"
            >
              {{ showScoreStandard ? '隐藏评分标准' : '评分标准' }}
            </button>
            <button
              @click="submitAssignment"
              class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 transition-colors"
            >
              提交 (Ctrl+S)
            </button> -->
            <button
              @click="resetCode"
              class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 transition-colors"
            >
              重置
            </button>
            <button
              @click="clearCode"
              class="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 transition-colors"
            >
              清空
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 评分标准显示区域 -->
    <div v-if="showScoreStandard" class="bg-white border-b shadow-sm fixed top-16 left-0 right-0 z-40">
      <div class="container mx-auto px-4 py-6">
        <div class="prose prose-sm max-w-none" v-html="scoreStandardContent"></div>
      </div>
    </div>

    <!-- 主要内容区域 -->
    <div class="container mx-auto px-4 py-6" :style="{ marginTop: showScoreStandard ? '200px' : '6px' }">
      <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 h-[calc(100vh-100px)] mb-6">
        <!-- 代码编辑器 -->
        <div class="bg-white rounded-lg shadow-sm border flex flex-col">
          <div class="p-4 border-b bg-gray-50 rounded-t-lg flex-shrink-0">
            <div class="flex justify-between items-center">
              <h2 class="text-lg font-semibold text-gray-800">代码编辑器</h2>
              <div class="flex items-center space-x-2">
                <input
                  ref="fileInputRef"
                  type="file"
                  accept=".html,.htm"
                  @change="handleFileUpload"
                  class="hidden"
                />
                <button
                  @click="downloadCode"
                  class="px-3 py-1.5 bg-green-500 hover:bg-green-600 text-white text-sm rounded-md transition-colors flex items-center space-x-1"
                >
                  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
                  </svg>
                  <span>下载代码</span>
                </button>
                <button
                  @click="triggerFileUpload"
                  class="px-3 py-1.5 bg-blue-500 hover:bg-blue-600 text-white text-sm rounded-md transition-colors flex items-center space-x-1"
                >
                  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
                  </svg>
                  <span>加载HTML文件</span>
                </button>
              </div>
            </div>
          </div>
          <div class="p-4 flex-1 overflow-auto" style="max-height: calc(100vh - 150px);">
            <textarea
              ref="codeEditorRef"
              v-model="code"
              class="w-full h-full resize-none border-0 outline-none code-editor"
              placeholder="在这里输入你的HTML代码..."
              style="min-height: 400px;"
            ></textarea>
          </div>
        </div>

        <!-- 预览区域 -->
        <div class="bg-white rounded-lg shadow-sm border flex flex-col">
          <div class="p-4 border-b bg-gray-50 rounded-t-lg flex-shrink-0">
            <h2 class="text-lg font-semibold text-gray-800">实时预览</h2>
          </div>
          <div class="p-4 flex-1 overflow-auto" style="height: calc(100vh - 400px);">
            <iframe
              ref="previewFrameRef"
              class="w-full border rounded"
              style="height: 100%; min-height: 300px;"
              title="代码预览"
            ></iframe>
          </div>
        </div>
      </div>
    </div>

    <!-- 状态消息 -->
    <div
      v-if="statusMessage.show"
      :class="getStatusClass(statusMessage.type)"
      class="fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg transition-all duration-300"
    >
      {{ statusMessage.text }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick, watch, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { useAssignmentStore } from '@/stores/assignment'
import { gradeAssignment, gradeAssignmentSync, downloadCode as utilDownloadCode } from '@/utils/util'
import { gradeVueAssignment } from '@/utils/vueGrading'
import { validateHTMLCode, safeParseSubmission, safeLocalStorage } from '@/utils/validation'
import type { Submission, StatusMessage } from '@/types/index'
import { GRADING_CONFIG, EDITOR_CONFIG, STORAGE_KEYS, ERROR_MESSAGES } from '@/config/constants'
import { marked } from 'marked'

// 引入 CodeMirror
import { EditorView, basicSetup } from 'codemirror'
import { html } from '@codemirror/lang-html'

const router = useRouter()
const assignmentStore = useAssignmentStore()

const codeEditorRef = ref<HTMLTextAreaElement>()
const previewFrameRef = ref<HTMLIFrameElement>()
const fileInputRef = ref<HTMLInputElement>()
const code = ref('')
const submissions = ref<Submission[]>([])
const submissionCount = ref(0)
const expandedFeedback = ref<number | null>(null)
const showScoreStandard = ref(false)
const scoreStandardContent = ref('')
const statusMessage = ref<StatusMessage>({
  show: false,
  text: '',
  type: 'info'
})

let codeMirrorEditor: EditorView | null = null
let previewTimeout: ReturnType<typeof setTimeout> | null = null

const currentAssignment = ref(assignmentStore.currentAssignment)
const currentExample = ref(assignmentStore.currentExample)

// 题目模板
const assignmentTemplates: Record<number, string> = {
  1: `<!DOCTYPE html>
<html>
<head>
    <title>个人简介</title>
</head>
<body>
    <h1>我的个人简介</h1>
    <!-- 在这里添加你的个人信息 -->
</body>
</html>`,
  2: `<!DOCTYPE html>
<html>
<head>
    <title>课程表</title>
</head>
<body>
    <h1>我的课程表</h1>
    <!-- 在这里创建课程表 -->
</body>
</html>`,
  3: `<!DOCTYPE html>
<html>
<head>
    <title>产品展示</title>
</head>
<body>
    <h1>产品展示</h1>
    <!-- 在这里展示产品 -->
</body>
</html>`,
  4: `<!DOCTYPE html>
<html>
<head>
    <title>导航菜单</title>
</head>
<body>
    <!-- 在这里创建导航菜单 -->
</body>
</html>`,
  5: `<!DOCTYPE html>
<html>
<head>
    <title>图片画廊</title>
</head>
<body>
    <h1>图片画廊</h1>
    <!-- 在这里创建图片画廊 -->
</body>
</html>`,
  6: `<!DOCTYPE html>
<html>
<head>
    <title>联系表单</title>
</head>
<body>
    <h1>联系我们</h1>
    <!-- 在这里创建联系表单 -->
</body>
</html>`
}

onMounted(async () => {
  if (!currentAssignment.value && !currentExample.value) {
    router.push('/')
    return
  }

  await nextTick()
  initCodeMirror()
  if (currentExample.value) {
    await loadExample()
  } else {
    loadAssignment()
  }
})

watch(() => assignmentStore.currentAssignment, (newAssignment) => {
  currentAssignment.value = newAssignment
  if (newAssignment) {
    loadAssignment()
  }
})

watch(() => assignmentStore.currentExample, async (newExample) => {
  currentExample.value = newExample
  if (newExample) {
    await loadExample()
  }
})

const initCodeMirror = () => {
  if (!codeEditorRef.value) return

  codeMirrorEditor = new EditorView({
    doc: code.value,
    extensions: [
      basicSetup,
      html(),
      EditorView.updateListener.of((update) => {
        if (update.docChanged) {
          code.value = update.state.doc.toString()
          if (previewTimeout) clearTimeout(previewTimeout)
          previewTimeout = setTimeout(previewCode, EDITOR_CONFIG.PREVIEW_DELAY)
        }
      }),
      EditorView.theme({
        '&': {
          fontSize: '14px',
          fontFamily: "'Consolas', '微软雅黑', 'Microsoft YaHei', 'Monaco', 'Courier New', monospace"
        },
        '.cm-content': {
          padding: '16px',
          minHeight: '400px',
          fontFamily: "'Consolas', '微软雅黑', 'Microsoft YaHei', 'Monaco', 'Courier New', monospace"
        },
        '.cm-lineNumbers': {
          fontFamily: "'Consolas', 'Monaco', 'Courier New', monospace"
        },
        '.cm-focused': {
          outline: 'none'
        }
      })
    ],
    parent: codeEditorRef.value.parentElement!
  })

  // 隐藏原始 textarea
  codeEditorRef.value.style.display = 'none'
}

const loadAssignment = () => {
  if (!currentAssignment.value) return

  const template = assignmentTemplates[currentAssignment.value.id]
  if (template) {
    code.value = template
    if (codeMirrorEditor) {
      codeMirrorEditor.dispatch({
        changes: {
          from: 0,
          to: codeMirrorEditor.state.doc.length,
          insert: template
        }
      })
    }
  }

  submissions.value = []
  submissionCount.value = 0
  setTimeout(previewCode, 100)
}

const loadExample = async () => {
  if (!currentExample.value) return

  let exampleContent = currentExample.value.content
  
  // 如果content为空，尝试从filePath加载
  if (!exampleContent && currentExample.value.filePath) {
    try {
      showStatus('正在加载示例文件...', 'info')
      const response = await fetch(currentExample.value.filePath)
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }
      exampleContent = await response.text()
      // 更新currentExample的content
      currentExample.value.content = exampleContent
    } catch (error: any) {
      console.error('Failed to load example file:', error)
      showStatus(`加载示例文件失败: ${error.message}`, 'error')
      return
    }
  }
  
  if (exampleContent) {
    code.value = exampleContent
    if (codeMirrorEditor) {
      codeMirrorEditor.dispatch({
        changes: {
          from: 0,
          to: codeMirrorEditor.state.doc.length,
          insert: exampleContent
        }
      })
    }
    showStatus('示例代码已加载', 'info')
  } else {
    showStatus('示例内容为空', 'warning')
  }

  submissions.value = []
  submissionCount.value = 0
  setTimeout(previewCode, 100)
}

const previewCode = () => {
  if (!previewFrameRef.value) return

  let htmlContent = code.value
  if (!htmlContent.includes('<meta charset=') && !htmlContent.includes('charset=')) {
    if (htmlContent.includes('<head>')) {
      htmlContent = htmlContent.replace('<head>', '<head>\n    <meta charset="UTF-8">')
    } else if (htmlContent.includes('<html>')) {
      htmlContent = htmlContent.replace('<html>', '<html>\n<head>\n    <meta charset="UTF-8">\n</head>')
    }
  }

  const blob = new Blob([htmlContent], { type: 'text/html;charset=utf-8' })
  const url = URL.createObjectURL(blob)
  previewFrameRef.value.src = url

  setTimeout(() => {
    URL.revokeObjectURL(url)
  }, 1000)

  showStatus('预览已更新！', 'info')
}

const toggleScoreStandard = async () => {
  showScoreStandard.value = !showScoreStandard.value
  
  if (showScoreStandard.value && !scoreStandardContent.value) {
    await loadScoreStandard()
  }
}

const loadScoreStandard = async () => {
  try {
    const response = await fetch('/score_std.md')
    if (!response.ok) {
      throw new Error('Failed to load score standard')
    }
    const markdownContent = await response.text()
    scoreStandardContent.value = await marked(markdownContent)
    showStatus('评分标准已加载', 'info')
  } catch (error) {
    console.error('Failed to load score standard:', error)
    showStatus('加载评分标准失败', 'error')
    scoreStandardContent.value = '<p>加载评分标准失败，请稍后重试。</p>'
  }
}

const submitAssignment = () => {
  if (!currentAssignment.value) {
    showStatus(ERROR_MESSAGES.NO_ASSIGNMENT, 'error')
    return
  }

  const trimmedCode = code.value.trim()
  if (!trimmedCode) {
    showStatus(ERROR_MESSAGES.EMPTY_CODE, 'error')
    return
  }

  // 验证HTML代码
  const validation = validateHTMLCode(trimmedCode)
  if (!validation.isValid) {
    showStatus(`${ERROR_MESSAGES.INVALID_HTML} ${validation.errors.join(', ')}`, 'error')
    return
  }

  submissionCount.value++
  showStatus('正在批改作业...', 'info')

  setTimeout(async () => {
    try {
      let gradingResult
      
      // 判断是否为Vue.js作业
      const isVueAssignment = isVueCode(trimmedCode) || 
        (currentAssignment.value?.title && currentAssignment.value.title.includes('个人信息卡'))
      
      if (isVueAssignment) {
        // 使用Vue.js专项评分系统
        showStatus('使用Vue.js专项评分系统...', 'info')
        try {
          gradingResult = await gradeVueAssignment(trimmedCode, 'personal-info-card')
          showStatus('Vue.js专项评分完成', 'info')
        } catch (vueError) {
          console.warn('Vue专项评分失败，回退到通用评分:', vueError)
          gradingResult = gradeAssignmentSync(trimmedCode, currentAssignment.value!.id)
        }
      } else {
        // 使用传统图像对比评分系统
        const referenceImagePath = `/src/assets/reference-images/assignment-${currentAssignment.value!.id}.png`
        
        try {
          // 尝试使用图像对比评分
          gradingResult = await gradeAssignment(trimmedCode, currentAssignment.value!.id, referenceImagePath)
          showStatus('使用图像对比评分中...', 'info')
        } catch (imageError) {
          console.warn('图像对比评分失败，使用备用SVG参考图:', imageError)
          // 回退到SVG参考图
          try {
            gradingResult = await gradeAssignment(trimmedCode, currentAssignment.value!.id, '/src/assets/reference-images/sample-todo.svg')
            showStatus('使用SVG参考图评分中...', 'info')
          } catch (svgError) {
            console.warn('SVG参考图评分失败，使用代码分析评分:', svgError)
            // 最终回退到代码分析
            gradingResult = gradeAssignmentSync(trimmedCode, currentAssignment.value!.id)
            showStatus('使用代码分析评分中...', 'info')
          }
        }
      }
      
      const submissionData: Submission = {
        id: submissionCount.value,
        assignmentTitle: currentAssignment.value!.title,
        code: trimmedCode,
        timestamp: new Date(),
        status: gradingResult.score >= GRADING_CONFIG.THRESHOLDS.PASS ? '已通过' : '需要修改',
        grade: gradingResult.grade,
        score: gradingResult.score,
        feedback: gradingResult.feedback
      }

      // 安全解析提交数据
      const parsedSubmission = safeParseSubmission(submissionData)
      if (parsedSubmission) {
        submissions.value.push(parsedSubmission)
        // 保存到本地存储
        safeLocalStorage.setItem(STORAGE_KEYS.SUBMISSIONS, submissions.value)
        
        // 显示评分结果
        const gradingMethod = isVueAssignment ? 'Vue.js专项评分' : '图像对比评分'
        if (gradingResult.score >= GRADING_CONFIG.THRESHOLDS.EXCELLENT) {
          showStatus(`🎉 优秀！得分：${gradingResult.score}/100 (${gradingResult.grade}) [${gradingMethod}]`, 'success')
        } else if (gradingResult.score >= GRADING_CONFIG.THRESHOLDS.GOOD) {
          showStatus(`👍 良好！得分：${gradingResult.score}/100 (${gradingResult.grade}) [${gradingMethod}]`, 'success')
        } else if (gradingResult.score >= GRADING_CONFIG.THRESHOLDS.PASS) {
          showStatus(`✅ 及格！得分：${gradingResult.score}/100 (${gradingResult.grade}) [${gradingMethod}]`, 'warning')
        } else {
          showStatus(`❌ 不及格！得分：${gradingResult.score}/100 (${gradingResult.grade}) [${gradingMethod}]`, 'error')
        }
      } else {
        showStatus(ERROR_MESSAGES.SUBMISSION_FAILED, 'error')
      }
    } catch (error) {
      console.error('提交失败:', error)
      showStatus(ERROR_MESSAGES.SUBMISSION_FAILED, 'error')
    }
  }, 1500)
}

// Vue.js代码检测函数
const isVueCode = (code: string): boolean => {
  const vueIndicators = [
    'new Vue(',
    'Vue.createApp(',
    'createApp(',
    'data:',
    'data()',
    '{{',
    'v-if',
    'v-for',
    'v-show',
    'v-bind',
    'v-model'
  ]
  
  return vueIndicators.some(indicator => code.includes(indicator))
}

// 评分相关函数已移动到 @/utils/util.js

const resetCode = () => {
  if (currentExample.value) {
    if (confirm('确定要重置代码到原始示例吗？')) {
      const exampleContent = currentExample.value.content
      if (exampleContent) {
        code.value = exampleContent
        if (codeMirrorEditor) {
          codeMirrorEditor.dispatch({
            changes: {
              from: 0,
              to: codeMirrorEditor.state.doc.length,
              insert: exampleContent
            }
          })
        }
        previewCode()
        showStatus('代码已重置到原始示例', 'info')
      }
    }
  } else if (currentAssignment.value) {
    if (confirm('确定要重置代码到初始模板吗？')) {
      const template = assignmentTemplates[currentAssignment.value.id]
      if (template) {
        code.value = template
        if (codeMirrorEditor) {
          codeMirrorEditor.dispatch({
            changes: {
              from: 0,
              to: codeMirrorEditor.state.doc.length,
              insert: template
            }
          })
        }
        previewCode()
        showStatus('代码已重置到初始模板', 'info')
      }
    }
  }
}

const clearCode = () => {
  if (confirm('确定要清空所有代码吗？')) {
    code.value = ''
    if (codeMirrorEditor) {
      codeMirrorEditor.dispatch({
        changes: {
          from: 0,
          to: codeMirrorEditor.state.doc.length,
          insert: ''
        }
      })
    }
    if (previewFrameRef.value) {
      previewFrameRef.value.src = 'about:blank'
    }
    showStatus('代码已清空', 'info')
  }
}

const goBackToSelect = () => {
  // 优先使用存储的返回路由信息
  if (assignmentStore.returnRoute) {
    const returnRoute = assignmentStore.returnRoute
    assignmentStore.clearCurrentExample()
    assignmentStore.clearCurrentAssignment()
    router.push({ path: returnRoute.path, query: returnRoute.query })
    return
  }
  
  // 如果没有存储的返回路由，使用原有的逻辑
  const source = assignmentStore.sourceType
  
  if (currentExample.value) {
    assignmentStore.clearCurrentExample()
    switch (source) {
      case 'chapter3-examples':
        router.push({ path: '/chapter3-examples', query: { tab: 'examples' } })
        break
      case 'chapter4-examples':
        router.push({ path: '/chapter4-examples', query: { tab: 'examples' } })
        break
      case 'examples':
        router.push({ path: '/examples', query: { tab: 'examples' } })
        break
      default:
        router.push('/')
        break
    }
  } else if (currentAssignment.value) {
    assignmentStore.clearCurrentAssignment()
    router.push('/')
  } else {
    router.push('/')
  }
}

const showStatus = (text: string, type: StatusMessage['type']) => {
  statusMessage.value = { show: true, text, type }
  setTimeout(() => {
    statusMessage.value.show = false
  }, 3000)
}

const toggleFeedback = (submissionId: number) => {
  expandedFeedback.value = expandedFeedback.value === submissionId ? null : submissionId
}

const getStatusClass = (type: string) => {
  const classes = {
    success: 'bg-green-500 text-white',
    error: 'bg-red-500 text-white',
    warning: 'bg-yellow-500 text-white',
    info: 'bg-blue-500 text-white'
  }
  return classes[type as keyof typeof classes]
}

const getDifficultyClass = (difficulty: string) => {
  const classes = {
    easy: 'bg-green-100 text-green-800',
    medium: 'bg-yellow-100 text-yellow-800',
    hard: 'bg-red-100 text-red-800'
  }
  return classes[difficulty as keyof typeof classes]
}

const getDifficultyText = (difficulty: string) => {
  const texts = {
    easy: '简单',
    medium: '中等',
    hard: '困难'
  }
  return texts[difficulty as keyof typeof texts]
}

// 下载代码文件
const downloadCode = () => {
  utilDownloadCode(code.value, 'code.html', showStatus)
}

// 文件上传相关函数
const triggerFileUpload = () => {
  if (fileInputRef.value) {
    fileInputRef.value.click()
  }
}

const handleFileUpload = (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]
  
  if (!file) return
  
  // 验证文件类型
  if (!file.name.toLowerCase().endsWith('.html') && !file.name.toLowerCase().endsWith('.htm')) {
    showStatus('请选择HTML文件（.html或.htm格式）', 'error')
    return
  }
  
  // 验证文件大小（限制为1MB）
  if (file.size > 1024 * 1024) {
    showStatus('文件大小不能超过1MB', 'error')
    return
  }
  
  const reader = new FileReader()
  reader.onload = (e) => {
    const content = e.target?.result as string
    if (content) {
      // 更新代码编辑器内容
      code.value = content
      if (codeMirrorEditor) {
        codeMirrorEditor.dispatch({
          changes: {
            from: 0,
            to: codeMirrorEditor.state.doc.length,
            insert: content
          }
        })
      }
      // 更新预览
      previewCode()
      showStatus(`已成功加载文件：${file.name}`, 'success')
    }
  }
  
  reader.onerror = () => {
    showStatus('文件读取失败，请重试', 'error')
  }
  
  reader.readAsText(file, 'UTF-8')
  
  // 清空input值，允许重复选择同一文件
  target.value = ''
}

// 键盘快捷键
const handleKeydown = (e: KeyboardEvent) => {
  if (e.ctrlKey && e.key === 'Enter') {
    e.preventDefault()
    previewCode()
  }
  if (e.ctrlKey && e.key === 's') {
    e.preventDefault()
    submitAssignment()
  }
}

onMounted(() => {
  document.addEventListener('keydown', handleKeydown)
})

// 清理
const cleanup = () => {
  document.removeEventListener('keydown', handleKeydown)
  if (previewTimeout) {
    clearTimeout(previewTimeout)
  }
}

// 组件卸载时清理
onUnmounted(cleanup)
</script>